
package com.x52im.rbchat.logic.search.impl;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.x52im.rbchat.logic.search.content.SearchableContent;
import com.x52im.rbchat.logic.search.model.ListViewItemData;
import com.x52im.rbchat.logic.search.model.SearchCompleteData;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.x52im.rbchat.R;
import com.x52im.rbchat.logic.search.viewholder.SeeMoreViewHolder;

/**
 * 搜索结果列表Adapter实现类。
 *
 * @author Jack Jiang
 * @since 8.2
 */
public class SearchResultListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    public final static String TAG = SearchResultListAdapter.class.getSimpleName();

    /** "搜索更多"item的viewType常量 */
    public final static int VIEW_TYPE_SEE_MORE = 1;

    /** 可搜索内容封装对象集合，key=viewType、value=SearchableContent对象 */
    private final HashMap<Integer, SearchableContent> searchableContent4ViewType = new HashMap<>();
    /** 搜索结果列表数据集合 */
    private final List<ListViewItemData> results = new ArrayList<>();
    /** 本类列表对应的fragment对象引用 */
    private final Fragment fragment;

    public SearchResultListAdapter(Fragment fragment) {
        this.fragment = fragment;
    }

    /**
     * 添加搜索结果并刷新ui显示。
     *
     * @param r 搜索结果数据封装对象
     */
    public void addSearchResult(SearchCompleteData r) {
        if (r.getSearchedResults() == null || r.getSearchedResults().isEmpty()) {
            Log.d(TAG, "submitSearResult时，查询结果是空的，result.result=" + r.getSearchedResults());
            return;
        }

        int newItemCount = r.getSearchedResultsSize();
        int startPosition = results.size();
        int viewType = r.getSearchableContent().getViewType();

        // 只显示默认数量的item
        for (int i = 0; i < r.getSearchedResultsSize() && (r.getSearchableContent().isShowAllResult()
                || i < SearchableContent.RESULT_LIST_ITEM_DEFAULT_SHOW_COUNT); i++) {
            boolean showCatlog = (i == 0);
            Object data = r.getSearchedResults().get(i);
            results.add(new ListViewItemData(viewType, showCatlog, data));
        }

        // 如果只显示有限数量的结果
        if(!r.getSearchableContent().isShowAllResult()) {
            // 超过默认显示条数则加一条"查看更多"item
            if (r.getSearchedResultsSize() > SearchableContent.RESULT_LIST_ITEM_DEFAULT_SHOW_COUNT) {
                ListViewItemData di = new ListViewItemData(VIEW_TYPE_SEE_MORE, false, null);
                di.setParentViewType(viewType);
                results.add(di);
                newItemCount += 1;
            }
        }

        // 将content对象引用按viewType保存起来备用
        searchableContent4ViewType.put(viewType, r.getSearchableContent());

        // 刷新列表ui显示
        notifyItemRangeInserted(startPosition, newItemCount);
    }

    /**
     * 清空/重置列表显示内容。
     */
    public void clearResult() {
        results.clear();
        searchableContent4ViewType.clear();
        notifyDataSetChanged();
    }

    /**
     * Called when RecyclerView needs a new {@link RecyclerView.ViewHolder} of the given type to represent
     * an item.
     *
     * @param parent   The ViewGroup into which the new View will be added after it is bound to
     *                 an adapter position.
     * @param viewType The view type of the new View.
     * @return
     */
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == VIEW_TYPE_SEE_MORE) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.search_result_item_see_more, parent, false);
            RecyclerView.ViewHolder holder = new SeeMoreViewHolder(view);
            setItemClickListener(holder, view);
            return holder;
        } else {
            SearchableContent model = searchableContent4ViewType.get(viewType);
            RecyclerView.ViewHolder holder = model.onCreateViewHolder(fragment, parent, viewType);
            setItemClickListener(holder, holder.itemView);
            return holder;
        }
    }

    /**
     * Called by RecyclerView to display the data at the specified position. This method should
     * update the contents of the {@link RecyclerView.ViewHolder#itemView} to reflect the item at the given
     * position.
     *
     * @param holder   The ViewHolder which should be updated to represent the contents of the
     *                 item at the given position in the data set.
     * @param position The position of the item within the adapter's data set.
     */
    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        ListViewItemData listViewItemData = results.get(position);
        if (listViewItemData == null) {
            Log.w(TAG, "onBindViewHolder时，无效的position=" + position + "，通过它获取到的dataItem=null!");
            return;
        }

        if (listViewItemData.getViewType() == VIEW_TYPE_SEE_MORE) {
            int parentViewType = listViewItemData.getParentViewType();
            SearchableContent parentModule = getContentType(parentViewType);
            if (parentModule == null) {
                Log.w(TAG, "onBindViewHolder时，无效的parentViewType=" + parentViewType + "，通过它获取到的parentModule=null!");
                return;
            }

            ((SeeMoreViewHolder) holder).onBind(parentModule.getCategory());
        } else {
            int viewType = listViewItemData.getViewType();
            SearchableContent module = getContentType(viewType);
            if (module == null) {
                Log.w(TAG, "onBindViewHolder时，无效的viewType=" + viewType + "，通过它获取到的module=null!");
                return;
            }

            module.onBind(fragment, holder, listViewItemData.getContentData(), listViewItemData.isShowCategory());
        }
    }

    /**
     * Returns the total number of items in the data set held by the adapter.
     *
     * @return 列表单元数量
     */
    @Override
    public int getItemCount() {
        return results.size();
    }

    /**
     * Return the view type of the item at position for the purposes of view recycling.
     *
     * @param position item索引位置
     * @return -1表示未找到，否则返回对应的viewType类型
     */
    @Override
    public int getItemViewType(int position) {
        int viewType = -1;
        if(checkPositionValid(position)) {
            ListViewItemData listViewItemData = results.get(position);
            if (listViewItemData != null)
                viewType = listViewItemData.getViewType();
        }
        else {
            Log.w(TAG, "getItemViewType时，无效的position=" + position);
        }
        return viewType;
    }

    /**
     * 列表单元点击事件处理方法。
     *
     * @param holder item对应的holder对象
     * @param view item对应的view对象
     */
    private void setItemClickListener(RecyclerView.ViewHolder holder, View view) {
        view.setOnClickListener(v -> {
            int position = holder.getAdapterPosition();

            if(!checkPositionValid(position)){
                Log.w(TAG, "processOnClick时，无效的position="+position);
                return;
            }

            ListViewItemData listViewItemData = results.get(position);
            if(listViewItemData == null){
                Log.w(TAG, "processOnClick时，无效的dataItem="+null);
                return;
            }

            if (holder instanceof SeeMoreViewHolder) {
                int parentViewType = listViewItemData.getParentViewType();
                SearchableContent parentModule = getContentType(parentViewType);
                if (parentModule == null) {
                    Log.w(TAG, "processOnClick时，无效的parentViewType=" + parentViewType + "，通过它获取到的module=null!");
                    return;
                }

                parentModule.doClickMore(fragment, v);
            } else {
                int viewType = listViewItemData.getViewType();
                SearchableContent module = getContentType(viewType);
                if (module == null) {
                    Log.w(TAG, "processOnClick时，无效的viewType=" + viewType + "，通过它获取到的module=null!");
                    return;
                }

                module.doClick(fragment, holder, v, listViewItemData.getContentData());
            }
        });
    }

    /**
     * 索引位置合法性检查。
     *
     * @param position 索引位置
     * @return true表示索引有效，否则无效
     */
    private boolean checkPositionValid(int position){
        return (position >=0 && position <= (this.results.size() - 1));
    }

    /**
     * 返回viewType对应的搜索内容对象。
     *
     * @param viewType 列表item对应的viewType
     * @return 存在则正常返回，否则返回null
     */
    private SearchableContent getContentType(int viewType){
        return searchableContent4ViewType.get(viewType);
    }
}
